import {
  createRouter,
  createWebHistory,
  createWebHashHistory,
  createMemoryHistory,
  RouteRecordRaw,
  useRouter,
  NavigationGuardWithThis,
  NavigationGuardNext,
  RouteLocationNormalized,
  RouteRecordName,
} from "vue-router";
import { defineAsyncComponent, Component } from "vue";
import { Config, EventBus, Store } from "../main";
import CommonRouter from "./common.router";
export interface JsonRoute {
  path: string;
  name: string;
  component: Component;
  redirect?: { [name: string]: string };
  title?: string;
  icon?: any;
  children?: Array<JsonRoute>;
}
/**
 *  将CommonRouter里面的路由解析出来
 * @param jsonRouteList
 * @returns
 */
const ExplainRoute = (jsonRouteList: Array<JsonRoute>): Array<RouteRecordRaw> => {
  return jsonRouteList.map(
    item =>
      ({
        path: item.path,
        name: item.name,
        redirect: item.redirect,
        component: item.component,
        children: item.children ? ExplainRoute(item.children) : undefined,
      } as RouteRecordRaw)
  );
};

/**
 * 为了制作面包屑以及标题栏
 */
const RouterNameTitleMap: Map<string, JsonRoute> = new Map();
const createNameTitleSet = (jsonRouteList: Array<JsonRoute>) => {
  jsonRouteList.forEach(item => {
    RouterNameTitleMap.set(item.name, item);
    item.children && createNameTitleSet(item.children);
  });
};
createNameTitleSet(CommonRouter);

const routes: Array<RouteRecordRaw> = ExplainRoute(CommonRouter);
const adminRoutes: Array<RouteRecordRaw> = [
  {
    path: "/",
    name: "Index",
    redirect: { name: "Admin" },
  },
  {
    path: "/Admin",
    name: "Admin",
    redirect: { name: routes[0].name },
    component: () => import("../layout/layout"),
    children: routes,
  },
  {
    path: "/Authoriation",
    name: "Authorization",
    component: () => import("../views/Authorization/Authorization.vue"),
  },
  {
    path: "/DataView",
    name: "DataView",
    component: () => import("../views/DataView/DataView.vue"),
  },
  {
    path: "/:catchAll(.*)",
    name: "404",
    component: () => import("../views/Error/404"),
  },
];

const router = createRouter({
  history: createWebHashHistory(),
  routes: adminRoutes,
});
//导出router
export { router };

router.beforeEach((to, from, next) => {
  if (from.name === to.name) return;
  if (Store.User.getUserInfo().isLogin === true) next();
  else {
    if (currentRoute().routeName === "Authorization") return;
    else if (to.name === "Authorization") next();
    else replacePage("Authorization");
  }
});
router.afterEach((to, from) => {
  if (adminRoutes.map(item => item.name).includes(to.name as RouteRecordName)) return;
  Store.Common.routerStack.set(to.name, RouterNameTitleMap.get(to.name as string)?.name);
  EventBus.emit(Config.Event.navigator, true);
});
const routerData = () => Store.Common.routerData;
const currentRoute = () => {
  const currnt = router.currentRoute.value;
  return {
    routeName: currnt.name as string,
    routePath: currnt.fullPath as string,
  };
};

/**
 * 跳转到其他页面，路由栈 push ，将新页面压入路由栈
 * @param routerPath 路由路径
 * @param data 携带的数据，跳转后的页面通过Nav.routerData()获取
 */
const navToPageByPath = (routerPath: string, data: any = null) => {
  if (router.currentRoute.value.path == routerPath) return;
  Store.Common.routerData = data;
  Store.Common.productionEnv = true;
  router.push({ path: routerPath });
};

/**
 * 跳转到其他页面，路由栈 push ，将新页面压入路由栈
 * @param routerName 路由名
 * @param data 携带的数据，跳转后的页面通过Nav.routerData()获取
 */
const navToPage = (routerName: string, data: any = null) => {
  if (router.currentRoute.value.name == routerName) return;
  Store.Common.routerData = data;
  Store.Common.productionEnv = true;
  router.push({ name: routerName });
};
/**
 * 跳转到其他页面，路由栈 replace ，将当前页替换成新页面
 * @param routerName 路由名
 * @param data 携带的数据，跳转后的页面通过Nav.routerData()获取
 */
const replacePage = (routerName: string, data: any = null) => {
  if (router.currentRoute.value.name == routerName) return;
  Store.Common.routerData = data;
  router.replace({ name: routerName });
};
/**
 * 回退到上一路由栈页面
 * @param data 携带的数据，跳转后的页面通过Nav.routerData()获取
 */
const navBack = (data: any = null) => {
  Store.Common.routerData = data;
  router.back();
};
const CreateNav = () => ({
  routerData,
  navToPage,
  navBack,
  replacePage,
  currentRoute,
  RouterNameTitleMap,
});
export default CreateNav;
